using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using InseSoft.Models.Entities;
using InseSoft.Models.Mapping;

namespace InseSoft.Models
{
    public class InseContext : DbContext, IInseContext
    {
        static InseContext()
        {
            Database.SetInitializer<InseContext>(null);
        }

        public InseContext() : base("Name=Context")
        {
        }
        
        public IDbSet<Cliente> Clientes { get; set; }
        public IDbSet<Cotizacion> Cotizaciones { get; set; }
        public IDbSet<Empresa> Empresas { get; set; }
        public IDbSet<Linea> Lineas { get; set; }
        public IDbSet<Material> Materiales { get; set; }
        public IDbSet<Orden> Ordenes { get; set; }
        public IDbSet<Permiso> Permisos { get; set; }
        public IDbSet<SolicitudCotizacion> SolicitudCotizaciones { get; set; }
        public IDbSet<TipoCambio> TipoCambios { get; set; }
        public IDbSet<TipoProducto> TipoProductos { get; set; }
        public IDbSet<Usuario> Usuarios { get; set; }
        public IDbSet<Vendedor> Vendedores { get; set; }

        public bool HasPendingChanges()
        {
            return ChangeTracker.Entries()
                      .Any(e => e.State == EntityState.Added
                             || e.State == EntityState.Deleted
                             || e.State == EntityState.Modified);
        }

        public IEnumerable<IEntity> AddedOrModifiedEntities<T>()
        {
            var states = new List<EntityState> {EntityState.Added, EntityState.Modified};
            return GetChangedEntities(states).Where(x => x.GetType() == typeof(T));
        }

        private IEnumerable<Entity> GetChangedEntities(IEnumerable<EntityState> states)
        {   
            return from e in ChangeTracker.Entries()
                   where states.Contains(e.State)
                   select e.Entity as Entity;
        }
        
        public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
        {
            return base.Set<TEntity>();
        }

        public void Save()
        {
            SaveChanges();
        }
        
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new ClienteMap());
            modelBuilder.Configurations.Add(new CotizacionMap());
            modelBuilder.Configurations.Add(new EmpresaMap());
            modelBuilder.Configurations.Add(new LineaMap());
            modelBuilder.Configurations.Add(new MaterialMap());
            modelBuilder.Configurations.Add(new OrdenMap());
            modelBuilder.Configurations.Add(new SolicitudCotizacionMap());
            modelBuilder.Configurations.Add(new TipoCambioMap());
            modelBuilder.Configurations.Add(new TipoProductoMap());
            modelBuilder.Configurations.Add(new VendedorMap());
            modelBuilder.Configurations.Add(new UsuarioMap());
            modelBuilder.Configurations.Add(new PermisoMap());
        }
    }
}
